#version 150

out vec4 FragColor;

smooth in vec3  positionInEyeSpace3;
smooth in vec3  normalInEyeSpace;

uniform vec3 ambientLight;

struct PointLight
{
   vec3 positionInEyeSpace;
   vec3 color;
   vec3 attenuation;
   float angle;
};
uniform PointLight pointLight;

struct MaterialProperties
{
   vec3 ambientColor;
   vec3 diffuseColor;
   vec3 specularColor;
   float specularExponent;
};
uniform MaterialProperties materialProperties;

float getAttenuation(in vec3 distanceVector)
{
   float r = length(distanceVector);
   return 1/(pointLight.attenuation.x + pointLight.attenuation.y * r + pointLight.attenuation.z * r * r); 
}

void main(void)
{
   // 1. Compute diffuse coeficient
   float diffuseCoeficient = max(0.0, dot(normalInEyeSpace, normalize(pointLight.positionInEyeSpace - positionInEyeSpace3)));  
   diffuseCoeficient *= getAttenuation(pointLight.positionInEyeSpace - positionInEyeSpace3);

   // 2. specular coeficient
   vec3 halfVector = normalize(-positionInEyeSpace3 + pointLight.positionInEyeSpace);
   float specularCoeficient = max(0.0, dot(halfVector, normalInEyeSpace));
   
   if (diffuseCoeficient == 0.0) //this vertex cannot be seen from camera position
   {
      specularCoeficient = 0.0;
   }
   else
   {
      specularCoeficient = pow(specularCoeficient, materialProperties.specularExponent);
   }

   // 3. final color computations
   vec3 color = ambientLight * materialProperties.ambientColor + 
            diffuseCoeficient * materialProperties.diffuseColor * pointLight.color + 
            specularCoeficient * materialProperties.specularColor * pointLight.color;

   FragColor = vec4( color, 1.0 );
}